package com.lizicloud.infrastructure.common.utils;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 日志工具类
 */
public class LogUtils {
    
    /**
     * 日志级别
     */
    public enum LogLevel {
        DEBUG, INFO, WARN, ERROR
    }
    
    private static LogLevel currentLevel = LogLevel.INFO;
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
    /**
     * 设置日志级别
     */
    public static void setLogLevel(LogLevel level) {
        currentLevel = level;
    }
    
    /**
     * 记录调试日志
     */
    public static void debug(String message) {
        log(LogLevel.DEBUG, message);
    }
    
    /**
     * 记录调试日志（带格式化）
     */
    public static void debug(String format, Object... args) {
        log(LogLevel.DEBUG, String.format(format, args));
    }
    
    /**
     * 记录信息日志
     */
    public static void info(String message) {
        log(LogLevel.INFO, message);
    }
    
    /**
     * 记录信息日志（带格式化）
     */
    public static void info(String format, Object... args) {
        log(LogLevel.INFO, String.format(format, args));
    }
    
    /**
     * 记录警告日志
     */
    public static void warn(String message) {
        log(LogLevel.WARN, message);
    }
    
    /**
     * 记录警告日志（带格式化）
     */
    public static void warn(String format, Object... args) {
        log(LogLevel.WARN, String.format(format, args));
    }
    
    /**
     * 记录错误日志
     */
    public static void error(String message) {
        log(LogLevel.ERROR, message);
    }
    
    /**
     * 记录错误日志（带格式化）
     */
    public static void error(String format, Object... args) {
        log(LogLevel.ERROR, String.format(format, args));
    }
    
    /**
     * 记录错误日志（带异常）
     */
    public static void error(String message, Throwable throwable) {
        log(LogLevel.ERROR, message + " - " + getStackTrace(throwable));
    }
    
    /**
     * 记录日志
     */
    private static void log(LogLevel level, String message) {
        if (level.ordinal() >= currentLevel.ordinal()) {
            String timestamp = DATE_FORMAT.format(new Date());
            String threadName = Thread.currentThread().getName();
            System.out.printf("[%s] [%s] [%s] %s%n", timestamp, level, threadName, message);
        }
    }
    
    /**
     * 获取异常的堆栈信息
     */
    public static String getStackTrace(Throwable throwable) {
        if (throwable == null) {
            return "";
        }
        
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        throwable.printStackTrace(pw);
        return sw.toString();
    }
    
    /**
     * 获取异常的简要信息
     */
    public static String getBriefStackTrace(Throwable throwable) {
        if (throwable == null) {
            return "";
        }
        
        StringBuilder sb = new StringBuilder();
        sb.append(throwable.getClass().getName()).append(": ").append(throwable.getMessage());
        
        StackTraceElement[] elements = throwable.getStackTrace();
        if (elements != null && elements.length > 0) {
            sb.append(" at ").append(elements[0].getClassName())
              .append(".").append(elements[0].getMethodName())
              .append("(").append(elements[0].getFileName())
              .append(":").append(elements[0].getLineNumber()).append(")");
        }
        
        return sb.toString();
    }
    
    /**
     * 记录方法开始执行
     */
    public static void logMethodStart(String methodName) {
        debug("方法开始执行: %s", methodName);
    }
    
    /**
     * 记录方法结束执行
     */
    public static void logMethodEnd(String methodName) {
        debug("方法结束执行: %s", methodName);
    }
    
    /**
     * 记录方法执行时间
     */
    public static void logMethodTime(String methodName, long startTime) {
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        debug("方法执行完成: %s, 耗时: %d ms", methodName, duration);
    }
    
    /**
     * 记录SQL执行
     */
    public static void logSql(String sql) {
        debug("SQL执行: %s", sql);
    }
    
    /**
     * 记录参数信息
     */
    public static void logParameters(String methodName, Object... params) {
        if (params == null || params.length == 0) {
            debug("方法 %s 参数: 无", methodName);
        } else {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < params.length; i++) {
                if (i > 0) sb.append(", ");
                sb.append("param").append(i + 1).append("=").append(params[i]);
            }
            debug("方法 %s 参数: %s", methodName, sb.toString());
        }
    }
    
    /**
     * 记录返回结果
     */
    public static void logResult(String methodName, Object result) {
        debug("方法 %s 返回: %s", methodName, result);
    }
    
    /**
     * 记录性能信息
     */
    public static void logPerformance(String operation, long startTime, long threshold) {
        long duration = System.currentTimeMillis() - startTime;
        if (duration > threshold) {
            warn("操作 %s 执行时间超过阈值: %d ms (阈值: %d ms)", operation, duration, threshold);
        } else {
            debug("操作 %s 执行时间: %d ms", operation, duration);
        }
    }
    
    private LogUtils() {
        // 私有构造函数，防止实例化
    }
}